package com.ruoyi.common.utils;

import org.apache.poi.ss.formula.functions.T;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Classname CollectionUtils
 * @Author: sunluquan
 * @Date: 2022/2/24 15:44
 * @Description TODO
 * 集合工具类
 */
public class CollectionUtils {

    public static final List EMPTY_LIST = new ArrayList(0);

    public static final Set EMPTY_SET = new HashSet(0);

    /**
     * 当前集合是否只存储了一个数据
     * @param ts
     * @return
     */
    public static boolean isSingle(Collection<Integer> ts){
        if(StringUtils.isNotEmpty(ts)){
            return ts.size()==1;
        }
        return Boolean.FALSE;
    }
    /**
     * 对于业务处理进行分离
     * @param ts 数据源
     * @param tConsumers 处理逻辑对象
     * @param <T>
     */
    public static <T> void businessOperation(Collection<T> ts, Consumer<T> ... tConsumers){
        if(StringUtils.isNotEmpty(ts) && StringUtils.isNotEmpty(tConsumers)){
            ts.forEach(item->{
                for (Consumer<T> tConsumer : tConsumers) {
                    tConsumer.accept(item);
                }
            });
        }
    }

    /**
     * 将集合中的每一个元素中的 某一个属性提取出来 变成一个集合并返回
     * @param es 集合数据
     * @param mapper 获取属性表达式
     * @param predicate 过滤表达式
     * @param <T>
     * @param <E>
     * @return 属性集合
     */
    public static <T,E> List<T> mapToList(Collection<E> es,Function<? super E, ? extends T> mapper,Predicate<? super E> predicate){

        if(StringUtils.isNotEmpty(es)){
            Stream<E> stream = es.stream();
            if(StringUtils.isNotNull(predicate)){
                return stream.filter(predicate).map(mapper).collect(Collectors.toList());
            }
            return stream.map(mapper).collect(Collectors.toList());
        }
        return EMPTY_LIST;
    }
    public static <T,E> List<T> mapToList(Collection<E> es,Function<? super E, ? extends T> mapper){
        return mapToList(es,mapper,null);
    }
    /**
     * 将集合中的每一个元素中的 某一个属性提取出来 变成一个集合并返回
     * @param es 集合数据
     * @param mapper 获取属性表达式
     * @param <T>
     * @param <E>
     * @return 属性集合
     */
    public static <T,E> Set<T> mapToSet(Collection<E> es,Function<? super E, ? extends T> mapper){

        if(StringUtils.isNotEmpty(es)){
            return es.stream().map(mapper).collect(Collectors.toSet());
        }
        return EMPTY_SET;
    }
    /**
     * 根据条件对 集合进行数据过滤
     * @param ts 集合
     * @param predicate 过滤表达式
     * @param <T>
     * @return
     */
    public static <T> List<T> filter(Collection<T> ts,Predicate<? super T> predicate){

        if(StringUtils.isNotEmpty(ts)) {
            return ts.stream().filter(predicate).collect(Collectors.toList());
        }

        return EMPTY_LIST;
    }
    /**
     * 获取集合元素中第一个 如果有的话
     * @param collection
     * @param <T>
     * @return
     */
    public static <T> T getFirst(Collection<T> collection){

        if(StringUtils.isNotEmpty(collection)){
            return collection.iterator().next();
        }

        return null;
    }

    private static <T> T filter(T t,Function<T,Boolean> condition){
        if(condition.apply(t)){
            return t;
        }
        return null;
    }

    /**
     * 查找符合条件的元素 并返回 无符合 返回null
     * @param list 查找源
     * @param condition
     * @param <T>
     * @return
     */
    public static <T> T find(@NotNull List<T> list,Function<T,Boolean> condition){
        T t = null;
        if (list.size()==1){
            t = filter(list.get(1), condition);
        }else{
            for (int i = 0; i < list.size(); i++) {
                t = filter(list.get(i), condition);
                if(StringUtils.isNotNull(t)){
                    break;
                }
            }
        }
        return t;
    }
    /**
     * 将 collection 集合转换为 map 默认value为 T 本身
     * @param data 集合数据
     * @param keyMapper map的key 获取器
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T, K> Map<K,T> toMap(@NotEmpty Collection<T> data,@NotNull Function<? super T, ? extends K> keyMapper){
        return toMap(data,keyMapper,(v)->v);
    }

    /**
     * 将 collection 集合转换为 map
     * @param data 集合数据
     * @param keyMapper map的key 获取器
     * @param valueMapper map的value 获取器
     * @param <T>
     * @param <K>
     * @param <U>
     * @return
     */
    public static <T, K ,U> Map<K,U> toMap(@NotEmpty Collection<T> data,@NotNull Function<? super T, ? extends K> keyMapper,
                                 @NotNull Function<? super T, ? extends U> valueMapper){
        return data.stream().collect(Collectors.toMap(keyMapper,valueMapper));
    }
}
